Public.ObjectiveC is a Pike module that can be used to integrate ObjectiveC objects and Pike. ObjectiveC is most commonly associated with the http://developer.apple.com development environment used in MacOS X. Why? Originally, I wanted to be able to integrate with the Growl system to allow me to send messages and notifications from my Pike apps. Later, I decided that it might be cool to be able to write native Cocoa apps in Pike. This is the (in-progress) result of this. Some of the features currently available in this module:
Pike v7.7 release 30 running Hilfe v3.5 (Incremental Pike Frontend) > import Public.ObjectiveC; > load_bundle("Message.framework"); (1) Result: 0 > Cocoa.NSMailDelivery.deliverMessage_subject_to_("whee", "test message", "hww3@riverweb.com"); (2) Result: 1
import Public.ObjectiveC; int i; object pool; void create() { Public.ObjectiveC.load_bundle("Growl.framework"); program g = get_dynamic_class("GrowlApplicationBridge"); g->setGrowlDelegate_(this); } int main() { call_out(notify, 6); return -1; } object p; mapping registrationDictionaryForGrowl(mixed ... args) { mapping n = ([]); n->ApplicationName = "PGrowl"; n->AllNotifications = ({"New Announcement"}); n->DefaultNotifications = ({"New Announcement"}); n->ApplicationIcon = Cocoa.NSWorkspace.sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(); return n; } void notify() { mapping n = ([]); n->ApplicationName = "PGrowl"; n->NotificationName = "New Announcement"; n->NotificationPriority = Cocoa.NSNumber.numberWithInt_(2); n->NotificationSticky = Cocoa.NSNumber.numberWithBool_(0); n->NotificationTitle = "notification from PGrowl"; n->NotificationDescription = "whooo, it's " Calendar.now()->format_smtp() "!ngreetings from Public.ObjectiveC!"; n->NotificationIcon = Cocoa.NSWorkspace.sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(); n->NotificationAppIcon = Cocoa.NSWorkspace.sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(); get_dynamic_class("GrowlApplicationBridge")->notifyWithDictionary_(n); // lather, rinse and repeat. call_out(notify, 5); }
import Public.ObjectiveC; int i; void create() { Public.ObjectiveC.low_load_bundle("/System/Library/Frameworks/Growl.framework"); NSClass("GrowlApplicationBridge")->setGrowlDelegate_(this); } int main() { call_out(notify, 6); return -1; } object p; object registrationDictionaryForGrowl(mixed ... args) { object n = Cocoa.NSMutableDictionary->dictionaryWithCapacity(2); n->setObject_forKey_("PGrowl", "ApplicationName"); n->setObject_forKey_(({"New Announcement"}), "AllNotifications"); n->setObject_forKey_(({"New Announcement"}), "DefaultNotifications"); n->setObject_forKey_(NSClass("NSWorkspace")->sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(), "ApplicationIcon"); return n; } void notify() { object n = Cocoa.NSMutableDictionary->dictionaryWithCapacity(6); n->setObject_forKey_("PGrowl", "ApplicationName"); n->setObject_forKey_("New Announcement", "NotificationName"); n->setObject_forKey_(Cocoa.NSNumber->new()->initWithInt_(2), "NotificationPriority"); n->setObject_forKey_(Cocoa.NSNumber->new()->initWithBool_(0), "NotificationSticky"); n->setObject_forKey_("notification from PGrowl", "NotificationTitle"); n->setObject_forKey_("whooo, it's " Calendar.now()->format_smtp() "!ngreetings from Public.ObjectiveC!", "NotificationDescription"); n->setObject_forKey_(NSClass("NSWorkspace")->sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(), "NotificationIcon"); n->setObject_forKey_(NSClass("NSWorkspace")->sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(), "NotificationAppIcon"); NSClass("GrowlApplicationBridge")->notifyWithDictionary_(n); call_out(notify, 5); }
import Public.ObjectiveC; array fields = ({ Cocoa.ABAddressBook.kABLastNameProperty, Cocoa.ABAddressBook.kABFirstNameProperty, Cocoa.ABAddressBook.kABEmailProperty }); int main() { object book = Cocoa.ABAddressBook.sharedAddressBook(); object p = book->people(); foreach(p;; object person) { array row = ({}); foreach(fields;; object f) { object fv = person->valueForKey_(f); if(object_program(fv) == Cocoa.ABMultiValue) row += ({(string)fv->valueAtIndex_(0) }); else row += ({(string)fv}); } write((row*",") + "n"); } }
#import <PikeInterpreter/OCPikeInterpreter.h> #import <Foundation/NSString.h> int main() { id i; struct svalue * sv; // required for console mode objective c applications NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init]; // these 3 lines set up and start the interpreter. i = [OCPikeInterpreter sharedInterpreter]; // we can optionally specify an alternate master, or use the one bundled in the framework. [i setMaster: @"/usr/local/pike/7.7.30/lib/master.pike"]; [i startInterpreter]; // ok, now that we have things set up, let's use it. // first, an example of calling pike c level apis directly. f_version(0); printf("%sn", Pike_sp[-1].u.string->str); pop_stack(); // next, we'll demonstrate one of the convenience functions available sv = [i evalString: @"1+2"]; printf("type: %d, value: %dn", sv->type, sv->u.integer); free_svalue(sv); // finally, we clean up. [i stopInterpreter]; [innerPool release]; return 0; }
import Public.ObjectiveC; object NSApp; class ConverterController { inherit Cocoa.NSObject; object exchangeRate; object dollarsToConvert; object convertedAmount; void convert_(object action) { float x; x = exchangeRate->floatValue() * dollarsToConvert->floatValue(); convertedAmount->setFloatValue_(x); } } int main(int argc, array argv) { NSApp = Cocoa.NSApplication.sharedApplication(); return AppKit()->NSApplicationMain(argc, argv); }